/**
 * 使用缩放
 * @param {*} outerDom 外面的dom
 * @param {*} svgDom 里面的svg
 * @param {*} minWidth 最小宽度px
 * @param {*} zoomValue 滚动一次缩放的像素px
 * @returns
 */
import {callWithAsyncErrorHandling, nextTick, onBeforeUnmount, onMounted, reactive, ref} from "vue";

export function useZoom() {
    //DOM操作
    let svgclip = ref(null);
    let svg = ref(null);
    let config = reactive({
        minWidth: 1920,
        //滚轮滚一次缩放多少的像素
        zoomValue: 100,
        //高度和宽度的比
        ratio:0.883,
        //外层盒子的DOM
        outerDom: undefined,
        //SVG的DOM
        svgDom: undefined,
    });
    //初始化
    function initZoom(zoomValue,ratio){
        config.zoomValue = zoomValue;
        config.ratio = ratio;
    }
    //挂载
    onMounted(() => {
        config.outerDom = svgclip.value;
        config.svgDom = svg.value;
        config.minWidth = svgclip.value.clientWidth;
        config.svgDom.style.width = config.minWidth + 'px'
        console.log(' config.minWidth',config.minWidth,'config.svgDom.style.width ',config.svgDom.style.width)
        startZoom();
    });

    onBeforeUnmount(() => {
        endZoom();
    });


    let startPoint ={
        x:0,
        y:0
    }
    let endPoint ={
        x:0,
        y:0
    }
    let offsetV2 = {
        x:0,
        y:0
    }

    let startScroll = {
        x:0,
        y:0
    }
    let moveFlag = false;
    //开始监听事件
    function startZoom() {
        //防止初始化报错
        if(config.svgDom === undefined){
            console.log("svgDom为空!");
            return;
        }else if(config.outerDom === undefined){
            console.log("outerDom为空!");
            return;
        }
        config.outerDom.addEventListener('mousewheel', mousewheelCall ,false);
        config.svgDom.addEventListener('mousedown', mousedownCall ,false);
        config.svgDom.addEventListener('mouseup', mouseupCall ,false);
        config.svgDom.addEventListener('mousemove', mousemoveCall ,false);
        config.svgDom.addEventListener('mouseout', mouseoutCall ,false);
        config.svgDom.oncontextmenu = function(){
            return false;
        }
    }

    /**
     * 缓动函数
     * @param a 初始值
     * @param b 目标值
     * @param p 比例
     * @returns {*} 动作完一次的结果值
     */
    function lerp(a, b, p)
    {
        //由于a永远无法等于b，当小于0.1的时候我让a=b
        if (Math.abs(a - b) < 0.1) return b;
        return a + (b - a) * p;
    }

    /**
     * 监听鼠标按下函数
     * @param event 鼠标按下的事件
     */
    function mousedownCall(event){
        event.preventDefault(); //阻止默认事件
        event.stopPropagation(); //停止冒泡
        if(event.button === 2||event.button === 1){
            moveFlag = true;
            startPoint.x = event.pageX;
            startPoint.y = event.pageY;
            startScroll.x = config.outerDom.scrollLeft;
            startScroll.y = config.outerDom.scrollTop;
        }
    }

    /**
     * 鼠标移除范围
     * @param event
     */
    function mouseoutCall(event){
        event.stopPropagation();
        event.preventDefault();
        if(!(event.target.nodeName === "svg" ||
            event.target.nodeName === "polyline" ||
            event.target.nodeName ==="use"||
            event.target.nodeName ==="line"||
            event.target.nodeName ==="polygon"||
            event.target.nodeName ==="circle"||
            event.target.nodeName ==="text"||
            event.target.nodeName ==="rect"))
            moveFlag = false;
    }

    /**
     * 鼠标移动的回调
     * @param event
     */
    function mousemoveCall(event){
        if(!moveFlag)return;
        event.preventDefault();
        event.stopPropagation();
        config.outerDom.scrollLeft = startScroll.x + startPoint.x - event.pageX;
        config.outerDom.scrollTop = startScroll.y + startPoint.y - event.pageY;
    }

    /**
     * 鼠标弹起的回调
     * @param event
     */
    function mouseupCall(event){
        event.preventDefault();
        event.stopPropagation();
        if(event.button === 2||event.button === 1)
            moveFlag = false;
    }

    let startValue; //开始滚动时候的宽度
    let endValue;
    let timer = null;
    /**
     * mousewheelCall监听鼠标滚轮的事件
     * @param event 事件对象
     * @returns {void} void
     */
    function mousewheelCall(event){
            //默认事件是上下滚动，我需要修改成放大缩小
            event.preventDefault();
            //往上滚动
            if (event.wheelDelta > 0) {
                startValue = config.svgDom.clientWidth;
                endValue = startValue + config.zoomValue;
                //清除定时器
                clearInterval(timer);
                timer = setInterval(()=>{
                    //lerp是缓动函数
                    startValue = lerp(startValue,endValue,0.1);
                    config.svgDom.style.width = startValue + 'px';
                    if(startValue >= endValue){
                        clearInterval(timer);
                    }
                },17);
            }
            //往下滚动
            if (event.wheelDelta < 0) {
                startValue = config.svgDom.clientWidth;
                endValue = startValue - config.zoomValue;
                clearInterval(timer);
                timer = setInterval(()=>{
                    if(startValue <= endValue || startValue < config.minWidth){
                        clearInterval(timer);
                    }else
                    {
                        startValue = lerp(startValue,endValue,0.1);
                        config.svgDom.style.width = startValue + 'px';
                    }
                },17);
                //不可以永久缩小，优化的地方缩放至中心
                //TODO
                if (config.svgDom.clientWidth < config.minWidth){
                    config.svgDom.style.width = config.minWidth + 'px';
                }
            }
    }

    function endZoom() {
        if(config.svgDom === undefined){
            console.log("svgDom为空!");
            return;
        }else if(config.outerDom === undefined){
            console.log("outerDom为空!");
            return;
        }
        config.outerDom.removeEventListener('mousewheel', mousewheelCall );
        config.svgDom.removeEventListener('mousedown', mousedownCall );
        config.svgDom.removeEventListener('mouseup', mouseupCall );
        config.svgDom.removeEventListener('mousemove', mousemoveCall );
        config.svgDom.removeEventListener('mouseout', mouseoutCall);

    }
    return {
        initZoom,
        svgclip,
        svg
    };
}
